package models

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"time"

	"gorm.io/gorm"
)

// 定义账单的属性
type Account struct {
	ID       int     `json:"id"`
	Amount   float64 `json:"amount"`                // 金额
	Date     Date    `json:"date" gorm:"type:date"` // 日期格式：2006-01-02
	Category string  `json:"category"`              // 收入或支出
	Reason   string  `json:"reason"`                //收入来源或支出原因
}

// 自定义 Date 类型
type Date time.Time

// 实现 MarshalJSON 方法
func (d Date) MarshalJSON() ([]byte, error) {
	formatted := time.Time(d).Format("2006-01-02")
	return json.Marshal(formatted)
}

// 实现 UnmarshalJSON 方法
func (d *Date) UnmarshalJSON(data []byte) error {
	var dateStr string
	if err := json.Unmarshal(data, &dateStr); err != nil {
		return err
	}
	parsed, err := time.Parse("2006-01-02", dateStr)
	if err != nil {
		return err
	}
	*d = Date(parsed)
	return nil
}

// 实现 driver.Valuer 接口
func (d Date) Value() (driver.Value, error) {
	return time.Time(d), nil
}

// 实现 sql.Scanner 接口
func (d *Date) Scan(value interface{}) error {
	if value == nil {
		*d = Date(time.Time{}) // 如果数据库中的值为 NULL，设置为零值
		return nil
	}
	if t, ok := value.(time.Time); ok {
		*d = Date(t)
		return nil
	}
	return fmt.Errorf("failed to scan Date: %v", value)
}

// BeforeSave 钩子：保存到数据库前格式化日期
func (a *Account) BeforeSave(tx *gorm.DB) error {
	// 将时分秒部分设置为零
	a.Date = Date(time.Date(time.Time(a.Date).Year(), time.Time(a.Date).Month(), time.Time(a.Date).Day(), 0, 0, 0, 0, time.UTC))
	return nil
}

// AfterFind 钩子：从数据库读取后格式化日期
func (a *Account) AfterFind(tx *gorm.DB) error {
	// 将时分秒部分设置为零
	a.Date = Date(time.Date(time.Time(a.Date).Year(), time.Time(a.Date).Month(), time.Time(a.Date).Day(), 0, 0, 0, 0, time.UTC))
	return nil
}
